(function () {
    function isVertical(position) {
        return position === "top" || position === "bottom";
    }

    var loadingCls = "button-loading-font anim-rotate";

    /**
     * 文字类型的按钮
     * @class BI.Button
     * @extends BI.BasicButton
     *
     * @cfg {JSON} options 配置属性
     * @cfg {'common'/'success'/'warning'/'ignore'} [options.level='common'] 按钮类型，用不同颜色强调不同的场景
     */
    BI.Button = BI.inherit(BI.BasicButton, {

        _const: {
            iconWidth: 18,
        },

        _defaultConfig: function (props) {
            var conf = BI.Button.superclass._defaultConfig.apply(this, arguments);

            var adaptiveHeight = 0;
            if (isVertical(props.iconPosition)) {
                // 图标高度和文字高度默认相等
                adaptiveHeight += (props.textHeight || 16) * 2;
                adaptiveHeight += props.iconGap || 0;
                var tGap = props.tgap || props.vgap || 2;
                var bGap = props.bgap || props.vgap || 2;
                adaptiveHeight += (tGap + bGap);
            }

            var clearMinWidth = props.block === true || props.clear === true || props.plain;

            return BI.extend(conf, {
                baseCls: (conf.baseCls || "") + " bi-button" + ((BI.isIE() && BI.isIE9Below()) ? " hack" : ""),
                attributes: {
                    tabIndex: 1,
                },
                minWidth: clearMinWidth ? 0 : 80,
                height: isVertical(props.iconPosition) ? adaptiveHeight : 24,
                shadow: props.clear !== true,
                isShadowShowingOnSelected: true,
                readonly: true,
                iconCls: "",
                level: "common",
                block: false, // 是否块状显示，即不显示边框，没有最小宽度的限制
                clear: false, // 是否去掉边框和背景
                ghost: false, // 是否幽灵显示, 即正常状态无背景
                loading: false, // 是否处于加载中
                light: false, // 是否使用浅色
                plain: false, // 是否是朴素按钮，和 clear 的区别是 plain 有悬浮效果
                textAlign: "center",
                whiteSpace: "nowrap",
                textWidth: null,
                textHeight: null,
                hgap: props.clear ? 0 : (props.plain && !props.text ? 4 : 10),
                vgap: 0,
                tgap: 0,
                bgap: 0,
                lgap: 0,
                rgap: 0,
                icon: "",
                iconGap: 0,
                iconPosition: "left",
            });
        },

        render: function () {
            var o = this.options, self = this;

            // 由于button默认情况下有个边框，所以要主动算行高
            var lineHeight, textHeight = o.textHeight;
            var hasBorder = false
            if (BI.isNumber(o.height)) {
                if (!isVertical(o.iconPosition)) {
                    if (o.clear || o.block || o.light) {
                        lineHeight = o.height;
                    } else {
                        hasBorder = true;
                        lineHeight = o.height;
                    }
                } else {
                    lineHeight = textHeight;
                }
            }
            if (!textHeight) {
                if (o.whiteSpace === "nowrap") {
                    textHeight = lineHeight;
                }
            }

            var iconInvisible = !o.loading && !o.iconCls && !o.icon;
            if (BI.isPlainObject(o.icon) && !o.loading) {
                this.icon = BI.createWidget(o.icon);
            } else {
                this.icon = BI.createWidget({
                    type: "bi.icon_label",
                    cls: o.loading ? loadingCls : (o.iconCls || o.icon),
                    width: this._const.iconWidth,
                    height: BI.pixFormat(lineHeight, hasBorder ? 2 : 0),
                    lineHeight: BI.pixFormat(lineHeight, hasBorder ? 2 : 0),
                    // 不设置，自定义按钮无法居中
                    iconWidth: o.iconWidth,
                    iconHeight: o.iconHeight,
                    invisible: iconInvisible,
                });
            }

            // 用户可能设置的 width 小于按钮的最小宽度
            var actualWidth = (o.minWidth > 0 && o.width < o.minWidth) ? o.minWidth : o.width;
            var textWidth = iconInvisible && o.width ? actualWidth - o.hgap * 2 : null;
            if (BI.isNotNull(o.textWidth)) {
                // textWidth 需要减去图标
                textWidth = o.textWidth - (iconInvisible || isVertical(o.iconPosition) ? 0 : this._const.iconWidth);
            }
            this.text = BI.createWidget({
                type: "bi.label",
                text: o.text,
                whiteSpace: o.whiteSpace,
                textAlign: o.textAlign,
                textWidth: textWidth,
                textHeight: BI.pixFormat(textHeight, hasBorder ? 2 : 0),
                height: BI.pixFormat(lineHeight, hasBorder ? 2 : 0),
                value: o.value,
                title: null,
            });
            var layoutType = "bi.horizontal";
            var gapContainer = {
                lgap: o.iconPosition === "left" && o.text ? o.iconGap : 0,
                rgap: o.iconPosition === "right" ? o.iconGap : 0,
                tgap: o.iconPosition === "top" ? o.iconGap : 0,
                bgap: o.iconPosition === "bottom" ? o.iconGap : 0,
            };
            var items = [this.icon, BI.extend({el: this.text}, gapContainer)];
            if (isVertical(o.iconPosition)) {
                layoutType = "bi.vertical";
            }
            if (o.iconPosition === "right" || o.iconPosition === "bottom") {
                items = [BI.extend({el: this.text}, gapContainer), this.icon];
            }
            // bi.center_adapt 作用：让 hgap 不影响 iconGap。
            BI.createWidget({
                type: "bi.center_adapt",
                horizontalAlign: o.textAlign,
                element: this,
                hgap: o.hgap,
                vgap: o.vgap,
                items: [{
                    type: layoutType,
                    horizontalAlign: "center",
                    verticalAlign: "middle",
                    items: items,
                }],
            });

            var classArr = ["block", "clear", "ghost", "plain", "loading", "light"];
            // 如果 options 对应的属性为 true 则给元素添加 class
            BI.each(classArr, function (_, clz) {
                if (BI.get(o, clz) === true) {
                    self.element.addClass(clz);
                }
            });

            if (o.minWidth > 0) {
                this.element.css({ "min-width": BI.pixFormat(o.minWidth) });
            }
        },

        doClick: function () {
            BI.Button.superclass.doClick.apply(this, arguments);
            if (this.isValid()) {
                this.fireEvent(BI.Button.EVENT_CHANGE, this);
            }
        },

        _setEnable: function (enable) {
            BI.Button.superclass._setEnable.apply(this, arguments);
            if (enable === true) {
                this.element.attr("tabIndex", 1);
            } else if (enable === false) {
                this.element.removeAttr("tabIndex");
            }
        },

        beforeClick: function () {
            return this.isLoading();
        },

        isLoading: function () {
            return this._loading === undefined ? this.options.loading : this._loading;
        },

        loading: function () {
            this._loading = true;
            this.element.addClass("loading");
            if (this.icon.loading) {
                this.icon.loading();
            } else {
                // loadingCls 可以覆盖 iconCls 所以不需要移除 iconCls
                this.icon.element.addClass(loadingCls);
                this.icon.setVisible(true);
            }
        },

        loaded: function () {
            this._loading = false;
            this.element.removeClass("loading");
            if (this.icon.loaded) {
                this.icon.loaded();
            } else {
                this.icon.element.removeClass(loadingCls);
                this.icon.setVisible(!!this.options.iconCls);
            }
        },

        setText: function (text) {
            BI.Button.superclass.setText.apply(this, arguments);
            this.text.setText(text);
        },

        setValue: function (text) {
            BI.Button.superclass.setValue.apply(this, arguments);
            if (!this.isReadOnly()) {
                this.text.setValue(text);
            }
        },

        setIcon: function (cls) {
            var o = this.options;
            if (this.icon && o.iconCls !== cls) {
                this.icon.element.removeClass(o.iconCls).addClass(cls);
                o.iconCls = cls;
            }
        },

        doRedMark: function () {
            this.text.doRedMark.apply(this.text, arguments);
        },

        unRedMark: function () {
            this.text.unRedMark.apply(this.text, arguments);
        },

        doHighLight: function () {
            this.text.doHighLight.apply(this.text, arguments);
        },

        unHighLight: function () {
            this.text.unHighLight.apply(this.text, arguments);
        },
    });
    BI.shortcut("bi.button", BI.Button);
    BI.Button.EVENT_CHANGE = "EVENT_CHANGE";
}());
